package com.co.notaweb.facade;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import com.co.notaweb.bussines.IAsignacionBussinesLocal;
import com.co.notaweb.bussines.ICalificacionBussinesLocal;
import com.co.notaweb.bussines.IColegioBussinesLocal;
import com.co.notaweb.bussines.ICursoBussinesLocal;
import com.co.notaweb.bussines.IDocenteBussinesLocal;
import com.co.notaweb.bussines.IEstudianteBussinesLocal;
import com.co.notaweb.bussines.IGradoBussinesLocal;
import com.co.notaweb.bussines.ILogroBussinesLocal;
import com.co.notaweb.bussines.ILogroEvaluadoBussinesLocal;
import com.co.notaweb.bussines.IMateriaBussinesLocal;
import com.co.notaweb.bussines.IPeriodoBussinesLocal;
import com.co.notaweb.bussines.IPersonaGenericaBussinesLocal;
import com.co.notaweb.bussines.ITipoCalificacionBussinesLocal;
import com.co.notaweb.bussines.system.IPersonaBussinesLocal;
import com.co.notaweb.entities.Asignacion;
import com.co.notaweb.entities.Calificacion;
import com.co.notaweb.entities.Colegio;
import com.co.notaweb.entities.Curso;
import com.co.notaweb.entities.Docente;
import com.co.notaweb.entities.Estudiante;
import com.co.notaweb.entities.Logro;
import com.co.notaweb.entities.LogroEvaluado;
import com.co.notaweb.entities.Materia;
import com.co.notaweb.entities.Periodo;
import com.co.notaweb.entities.Persona;
import com.co.notaweb.entities.PersonaGenerica;
import com.co.notaweb.entities.system.Rol;
import com.co.notaweb.enums.EstadoEnum;
import com.co.notaweb.facade.system.ISistemaFacadeLocal;
import com.co.notaweb.util.Constants;

/**
 * @author PC
 * @version 1.0
 * @created 13-nov-2011 12:14:23
 */
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class ColegioFacade implements IColegioFacadeLocal {

	@EJB
	private ISistemaFacadeLocal sistemaFacade;

	@EJB
	private ICalificacionBussinesLocal calificacionBussines;
	@EJB
	private ICursoBussinesLocal cursoBussines;
	@EJB
	private IPersonaBussinesLocal personaBussines;
	@EJB
	private IDocenteBussinesLocal docenteBussines;
	@EJB
	private IEstudianteBussinesLocal estudianteBussines;
	@EJB
	private IGradoBussinesLocal gradoGradoBussines;
	@EJB
	private ILogroBussinesLocal logroBussines;
	@EJB
	private ILogroEvaluadoBussinesLocal logroEvaluadoBussines;
	@EJB
	private IMateriaBussinesLocal materiaBussines;
	@EJB
	private IPeriodoBussinesLocal periodoBussines;
	@EJB
	private ITipoCalificacionBussinesLocal tipoCalificacionBussines;
	@EJB
	private IAsignacionBussinesLocal asignacionBussines;
	@EJB
	private IColegioBussinesLocal colegioBussines;
	@EJB
	private IPersonaGenericaBussinesLocal personaGenericaBussines;

	/**
	 ******************************************************************************************************************** 
	 * CursoBussines
	 ******************************************************************************************************************** 
	 */

	public List<Curso> consultarCursosPorDocente(long idDocente) {
		return cursoBussines.consultarCursosPorDocente(idDocente);
	}

	public List<Curso> consultarCursosPorColegio(long idColegio) {
		return cursoBussines.consultarCursosPorColegio(idColegio);
	}

	/**
	 ******************************************************************************************************************** 
	 * CalificacionBussines
	 ******************************************************************************************************************** 
	 */

	public void createCalificacion(Calificacion calificacion) {
		calificacionBussines.create(calificacion);
	}

	/**
	 ******************************************************************************************************************** 
	 * LogroEvaluadoBussines
	 ******************************************************************************************************************** 
	 */
	public void createLogroEvaluado(LogroEvaluado logroEvaluado) {
		logroEvaluadoBussines.create(logroEvaluado);
	}

	/**
	 ******************************************************************************************************************** 
	 * MateriaBusines
	 ******************************************************************************************************************** 
	 */
	public List<Materia> consultarMateriasPorCursoDocente(long idCurso,
			long idDocente) {
		return materiaBussines.consultarMateriasPorCursoDocente(idCurso,
				idDocente);
	}

	public List<Materia> consultarAllMaterias() {
		return materiaBussines.consultarAllMaterias();
	}

	/**
	 ******************************************************************************************************************** 
	 * PeriodoBussines
	 ******************************************************************************************************************** 
	 */

	public Periodo findPeriodo(long idDocente) {
		return periodoBussines.find(idDocente);
	}

	public List<Periodo> consultarPeriodosColegio(long idColegio) {
		return periodoBussines.consultarPeriodosColegio(idColegio);
	}

	/**
	 ******************************************************************************************************************** 
	 * PersonaBussines
	 ******************************************************************************************************************** 
	 */

	public List<Persona> consultarAllPersonas() {
		List<Persona> personas = personaBussines.consultarAllPersonas();

		if (personas.size() > 0) {
			return personas;
		}
		return null;
	}
	
	public void createPersona(Persona persona, long idRol, String tipoPersona) {
		persona.getUsuario().setRoles(new ArrayList<Rol>());
		sistemaFacade.createUsuario(persona.getUsuario());
		Rol rol = sistemaFacade.findRol(idRol);
		if (!rol.getUsuarios().contains(persona.getUsuario())) {
			rol.getUsuarios().add(persona.getUsuario());
		}
		sistemaFacade.editRol(rol);

		if (tipoPersona.equalsIgnoreCase(Constants.PERSONA_TIPO_ESTUDIANTE)) {
			Estudiante estudiante = new Estudiante();
			estudiante.setCodigo(persona.getCodigo());
			estudiante.setDocumento(persona.getDocumento());
			estudiante.setNombre(persona.getNombre());
			estudiante.setApellido(persona.getApellido());
			estudiante.setUsuario(persona.getUsuario());
			estudianteBussines.create(estudiante);
		} else if (tipoPersona.equalsIgnoreCase(Constants.PERSONA_TIPO_DOCENTE)) {
			Docente docente = new Docente();
			docente.setCodigo(persona.getCodigo());
			docente.setDocumento(persona.getDocumento());
			docente.setNombre(persona.getNombre());
			docente.setApellido(persona.getApellido());
			docente.setUsuario(persona.getUsuario());
			docenteBussines.create(docente);
		} else if (tipoPersona
				.equalsIgnoreCase(Constants.PERSONA_TIPO_GENERICA)) {
			PersonaGenerica personaGenerica = new PersonaGenerica();
			personaGenerica.setCodigo(persona.getCodigo());
			personaGenerica.setDocumento(persona.getDocumento());
			personaGenerica.setNombre(persona.getNombre());
			personaGenerica.setApellido(persona.getApellido());
			personaGenerica.setUsuario(persona.getUsuario());
			personaGenericaBussines.create(personaGenerica);
		}
	}

	public void deletePersona(Persona persona, long idRol, String tipoPersona) {
		persona.getUsuario().setRoles(new ArrayList<Rol>());
		sistemaFacade.deleteUsuario(persona.getUsuario());
		Rol rol = sistemaFacade.findRol(idRol);
		if (!rol.getUsuarios().contains(persona.getUsuario())) {
			rol.getUsuarios().add(persona.getUsuario());
		}
		sistemaFacade.editRol(rol);

		if (tipoPersona.equalsIgnoreCase(Constants.PERSONA_TIPO_ESTUDIANTE)) {
			Estudiante estudiante = new Estudiante();
			estudiante.setCodigo(persona.getCodigo());
			estudiante.setDocumento(persona.getDocumento());
			estudiante.setNombre(persona.getNombre());
			estudiante.setApellido(persona.getApellido());
			estudiante.setUsuario(persona.getUsuario());
			estudianteBussines.create(estudiante);
		} else if (tipoPersona.equalsIgnoreCase(Constants.PERSONA_TIPO_DOCENTE)) {
			Docente docente = new Docente();
			docente.setCodigo(persona.getCodigo());
			docente.setDocumento(persona.getDocumento());
			docente.setNombre(persona.getNombre());
			docente.setApellido(persona.getApellido());
			docente.setUsuario(persona.getUsuario());
			docenteBussines.create(docente);
		} else if (tipoPersona
				.equalsIgnoreCase(Constants.PERSONA_TIPO_GENERICA)) {
			PersonaGenerica personaGenerica = new PersonaGenerica();
			personaGenerica.setCodigo(persona.getCodigo());
			personaGenerica.setDocumento(persona.getDocumento());
			personaGenerica.setNombre(persona.getNombre());
			personaGenerica.setApellido(persona.getApellido());
			personaGenerica.setUsuario(persona.getUsuario());
			personaGenericaBussines.create(personaGenerica);
		}
	}

	
	/**
	 ******************************************************************************************************************** 
	 * EstudianteBussines
	 ******************************************************************************************************************** 
	 */
	public List<Estudiante> consultarEstudiantesPorCursoMateriaDocente(
			long idCurso, long idMateria, long idDocente) {
		return estudianteBussines.consultarEstudiantesPorCursoMateriaDocente(
				idCurso, idMateria, idDocente);
	}

	public void createEstudiante(Estudiante estudiante) {
		estudianteBussines.create(estudiante);
	}

	public void editEstudiante(Estudiante estudiante) {
		estudianteBussines.edit(estudiante);
	}

	public void deleteEstudiante(Estudiante estudiante) {
		estudianteBussines.delete(estudiante);
	}

	public void findEstudiante(long id) {
		estudianteBussines.find(id);
	}

	public List<Estudiante> consultarEstudiantesPorCurso(long idCurso) {
		return estudianteBussines.consultarEstudiantesPorCurso(idCurso);
	}

	public List<Estudiante> consultarEstudiantesNoAsignadosCurso(
			List<Long> idsEstdiantes) {
		List<Estudiante> estudiantes = estudianteBussines
				.consultarEstudiantesPorNotIds(idsEstdiantes);
		if (estudiantes.size() > 0) {
			return estudiantes;
		}
		return null;
	}

	public void asignarEstudiantesACurso(List<Long> estudiantesAsignados,
			List<Long> estudiantesDisponibles, long idCurso) {

		Curso c = cursoBussines.find(idCurso);
		c.getEstudiantes().clear();

		List<Estudiante> asignados = estudianteBussines
				.consultarEstudiantesPorIds(estudiantesAsignados);

		List<Estudiante> disponibles = estudianteBussines
				.consultarEstudiantesPorIds(estudiantesDisponibles);

		for (Estudiante estudiante : asignados) {
			estudiante.setCurso(c);
			estudianteBussines.edit(estudiante);
		}

		for (Estudiante estudiante : disponibles) {
			estudiante.setCurso(null);
			estudianteBussines.edit(estudiante);
		}

		c.getEstudiantes().addAll(asignados);
		cursoBussines.edit(c);
	}

	/**
	 ******************************************************************************************************************** 
	 * LogroBussines
	 ******************************************************************************************************************** 
	 */
	public List<Logro> consultarLogrosPorCursoDocenteMateria(long idCurso,
			long idDocente, long idMateria) {
		return logroBussines.consultarLogrosPorCursoDocenteMateria(idCurso,
				idDocente, idMateria);
	}

	public List<Logro> consultarLogrosPorCursoDocenteMateriaPeriodo(
			long idCurso, long idDocente, long idMateria, long idPeriodo) {
		return logroBussines.consultarLogrosPorCursoDocenteMateriaPeriodo(
				idCurso, idDocente, idMateria, idPeriodo);
	}

	public void createLogro(Logro logro, Periodo periodo, Asignacion asignacion) {
		logroBussines.create(logro);
		asignacion.getLogros().add(logro);
		periodo.getLogros().add(logro);
		periodoBussines.edit(periodo);
		asignacionBussines.edit(asignacion);
	}

	/**
	 ******************************************************************************************************************** 
	 * asignacionBussines
	 * 
	 * @param idCurso
	 * @param idDocente
	 * @param idMateria
	 ******************************************************************************************************************** 
	 */
	public Asignacion consultarAsignacionPorCursoDocenteMateria(long idCurso,
			long idDocente, long idMateria) {
		List<Asignacion> asingnaciones = asignacionBussines
				.consultarAsignacionPorCursoDocenteMateria(idCurso, idDocente,
						idMateria);
		if (!asingnaciones.isEmpty()) {
			return asingnaciones.get(0);
		}
		return null;
	}

	public List<Asignacion> consultarAllAsignacion() {
		return asignacionBussines.consultarAllAsignacion();
	}

	public void editAsignacion(Asignacion asignacion, long idColegio,
			long idCurso, long idDocente, long idMateria) {
		asignacion.setColegio(colegioBussines.find(idColegio));
		asignacion.setCurso(cursoBussines.find(idCurso));
		asignacion.setDocente(docenteBussines.find(idDocente));
		asignacion.setMateria(materiaBussines.find(idMateria));

		asignacionBussines.edit(asignacion);
	}

	public void createAsignacion(Asignacion asignacion, long idColegio,
			long idCurso, long idDocente, long idMateria) {
		asignacion.setEstado(EstadoEnum.ACTIVO);
		asignacion.setColegio(colegioBussines.find(idColegio));
		asignacion.setCurso(cursoBussines.find(idCurso));
		asignacion.setDocente(docenteBussines.find(idDocente));
		asignacion.setMateria(materiaBussines.find(idMateria));

		asignacionBussines.create(asignacion);
	}

	public void deleteAsignacion(long idAsignacion) {
		Asignacion asignacion = asignacionBussines.find(idAsignacion);
		asignacion.setEstado(EstadoEnum.INACTIVO);
		asignacionBussines.edit(asignacion);
	}

	/**
	 ******************************************************************************************************************** 
	 * colegioBussines
	 * 
	 * @param coliegio
	 * @param idColegio
	 ******************************************************************************************************************** 
	 */
	public void createColegio(Colegio colegio) {
		colegioBussines.create(colegio);
	}

	public void editColegio(Colegio colegio) {
		colegioBussines.edit(colegio);
	}

	public void deleteColegio(Colegio colegio) {
		colegioBussines.delete(colegio);
	}

	public void findColegio(long id) {
		colegioBussines.find(id);
	}

	public List<Colegio> consultarAllColegios() {
		List<Colegio> colegios = colegioBussines.consultarAllColegios();

		if (colegios.size() > 0) {
			return colegios;
		}
		return null;
	}
	
	public List<Colegio> consultarColegiosByDocente(long idDocente) {
		List<Colegio> colegios = colegioBussines.consultarColegiosByDocente(idDocente);

		if (colegios.size() > 0) {
			return colegios;
		}
		return null;
	}

	

	/**
	 ******************************************************************************************************************** 
	 * docenteBussines
	 ******************************************************************************************************************** 
	 */
	public List<Docente> consultarDocentePorColegio(long idColegio) {
		return docenteBussines.consultarDocentePorColegio(idColegio);
	}

	public void createDocente(Docente docente) {
		docenteBussines.create(docente);
	}

	public void editDocente(Docente docente) {
		docenteBussines.edit(docente);
	}

	public void deleteDocente(Docente docente) {
		docenteBussines.delete(docente);
	}

	public void findDocente(long id) {
		docenteBussines.find(id);
	}

	public List<Docente> consultarDocenteNoAsignadosColegio(
			List<Long> idsDocente) {

		List<Docente> docentes = docenteBussines
				.consultarDocentesPorNotIds(idsDocente);

		if (docentes.size() > 0) {
			return docentes;
		}
		return null;
	}

	public void asignarDocentesAColegio(List<Long> docentesAsignados,
			List<Long> docentesDisponibles, long idColegio) {
		Colegio c = colegioBussines.find(idColegio);
		c.getDocentes().clear();

		List<Docente> asignados = docenteBussines
				.consultarDocentesPorIds(docentesAsignados);

		List<Docente> disponibles = docenteBussines
				.consultarDocentesPorIds(docentesDisponibles);

		for (Docente docente : asignados) {
			if (!docente.getColegios().contains(c)) {
				docente.getColegios().add(c);
			}
			docenteBussines.edit(docente);
		}

		for (Docente docente : disponibles) {
			docente.getColegios().remove(c);
			docenteBussines.edit(docente);
		}

		c.getDocentes().addAll(asignados);
		colegioBussines.edit(c);
	}

	/**
	 ******************************************************************************************************************** 
	 * personaGenericaBussines
	 ******************************************************************************************************************** 
	 */

	public void createPersonaGenerica(PersonaGenerica personaGenerica) {
		personaGenericaBussines.create(personaGenerica);
	}

	public void editPersonaGenerica(PersonaGenerica personaGenerica) {
		personaGenericaBussines.edit(personaGenerica);
	}

	public void deletePersonaGenerica(PersonaGenerica personaGenerica) {
		personaGenericaBussines.delete(personaGenerica);
	}

	public void findPersonaGenerica(long id) {
		personaGenericaBussines.find(id);
	}

}
